import type {CSSProperties, PropType} from "vue";
import {defineComponent} from "vue";
import {Icon} from "@iconify/vue";

// horizontal: 水平翻转 ，vertical：垂直翻转
type FlipType = "horizontal" | "vertical";
// 数字代表旋转角度  0° 90° 180° 270°
type RotateType = 0 | 1 | 2 | 3;

/**
 * SvgIcon 组件
 * @date 2023/9/26
 */
export default defineComponent({
  name: "SvgIcon",
  props: {
    // 图标名字
    icon: {
      type: String,
      required: true,
      default: "",
    },
    // 是否为本地 svg 图标
    isLocal: {
      type: Boolean,
      default: false,
    },
    // 图标大小
    size: {
      type: [Number, String],
      default: 14,
    },
    // 旋转角度
    rotate: {
      type: Number as PropType<RotateType>,
      default: 0,
    },
    // 图标翻转（水平翻转、垂直翻转）
    flip: String as PropType<FlipType>,
    // 图标旋转动画效果
    spin: {
      type: Boolean,
      default: false,
    },
    // 单独图标样式
    iconStyle: Object as PropType<CSSProperties>,
    // 图标颜色
    color: String,
    // 点击图标触发事件
    onClick: Function as PropType<(e: MouseEvent) => void>,
  },
  setup(props, { attrs }) {
    const bindAttrs = computed<{ class: string; style: string }>(() => ({
      class: (attrs.class as string) || "",
      style: (attrs.style as string) || "",
    }));

    const symbolId = () => `#${process.env.VITE_SVG_ICON_PREFIX}-${props.icon}`;

    const rotate = [0, 90, 180, 270];

    const localIconStyle = {
      width: "1em",
      height: "1em",
      lineHeight: "1em",
      fontSize: `${`${props.size}`.replace("px", "")}px`,
      animation: props.spin ? "circle 3s infinite linear" : "",
      transform: (() => {
        const scale = props.flip
          ? props.flip == "vertical"
            ? "scaleY(-1)"
            : props.flip == "horizontal"
            ? "scaleX(-1)"
            : ""
          : "";
        return `rotate(${rotate[props.rotate]}deg) ${scale}`;
      })(),
    };

    const iconStyles = { outline: "none", animation: props.spin ? "circle 3s infinite linear" : "" };
    return () => (
      <b
        onClick={e => {
          props.onClick?.(e);
        }}
        class={["inline-block", bindAttrs.value.class, props.onClick ? "cursor-pointer" : ""]}
        style={bindAttrs.value.style}
      >
        {props.isLocal ? (
          <svg aria-hidden="true" style={props.iconStyle ? Object.assign(localIconStyle, props.iconStyle) : localIconStyle}>
            <use xlinkHref={symbolId()} fill="currentColor" />
          </svg>
        ) : (
          <Icon
            icon={props.icon}
            width={props.size}
            height={props.size}
            rotate={props.rotate}
            flip={props.flip}
            color={props.color}
            style={props.iconStyle ? Object.assign(iconStyles, props.iconStyle) : iconStyles}
          />
        )}
      </b>
    );
  },
});
